home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / gchess40.lha / gnuchess4.0p62 / src / eval.c < prev    next >
C/C++ Source or Header  |  1993-06-22  |  40KB  |  1,600 lines

  1. /*
  2.  * eval.c - C source for GNU CHESS
  3.  *
  4.  * Copyright (c) 1988,1989,1990 John Stanback
  5.  * Copyright (c) 1992 Free Software Foundation
  6.  *
  7.  * This file is part of GNU CHESS.
  8.  *
  9.  * GNU Chess is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2, or (at your option)
  12.  * any later version.
  13.  *
  14.  * GNU Chess is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with GNU Chess; see the file COPYING.  If not, write to
  21.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23. #include "gnuchess.h"
  24. #include "ataks.h"
  25. int EADD = 0;
  26. int EGET = 0;
  27. int PUTVAR = false;
  28. #ifdef CACHE
  29. struct etable etab[2][ETABLE];
  30. #endif
  31.  
  32. short int sscore[2];
  33. /* Backward pawn bonus indexed by # of attackers on the square */
  34. static const short BACKWARD[16] =
  35. {-6, -10, -15, -21, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28};
  36.  
  37. /* Bishop mobility bonus indexed by # reachable squares */
  38. static const short BMBLTY[14] =
  39. {-2, 0, 2, 4, 6, 8, 10, 12, 13, 14, 15, 16, 16, 16};
  40.  
  41. /* Rook mobility bonus indexed by # reachable squares */
  42. static const short RMBLTY[15] =
  43. {0, 2, 4, 6, 8, 10, 11, 12, 13, 14, 14, 14, 14, 14, 14};
  44.  
  45. /* Positional values for a dying king */
  46. static const short DyingKing[64] =
  47. {0, 8, 16, 24, 24, 16, 8, 0,
  48.  8, 32, 40, 48, 48, 40, 32, 8,
  49.  16, 40, 56, 64, 64, 56, 40, 16,
  50.  24, 48, 64, 72, 72, 64, 48, 24,
  51.  24, 48, 64, 72, 72, 64, 48, 24,
  52.  16, 40, 56, 64, 64, 56, 40, 16,
  53.  8, 32, 40, 48, 48, 40, 32, 8,
  54.  0, 8, 16, 24, 24, 16, 8, 0};
  55.  
  56. /* Isoloted pawn penalty by rank */
  57. static const short ISOLANI[8] =
  58. {-12, -16, -20, -24, -24, -20, -16, -12};
  59.  
  60. /* table for King Bishop Knight endings */
  61. static const short KBNK[64] =
  62. {99, 90, 80, 70, 60, 50, 40, 40,
  63.  90, 80, 60, 50, 40, 30, 20, 40,
  64.  80, 60, 40, 30, 20, 10, 30, 50,
  65.  70, 50, 30, 10, 0, 20, 40, 60,
  66.  60, 40, 20, 0, 10, 30, 50, 70,
  67.  50, 30, 10, 20, 30, 40, 60, 80,
  68.  40, 20, 30, 40, 50, 60, 80, 90,
  69.  40, 40, 50, 60, 70, 80, 90, 99};
  70.  
  71. /* penalty for threats to king, indexed by number of such threats */
  72. static const short KTHRT[36] =
  73. {0, -8, -20, -36, -52, -68, -80, -80, -80, -80, -80, -80,
  74.  -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80,
  75.  -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80};
  76.  
  77. /* King positional bonus inopening stage */
  78. static const short KingOpening[64] =
  79. {0, 0, -4, -10, -10, -4, 0, 0,
  80.  -4, -4, -8, -12, -12, -8, -4, -4,
  81.  -12, -16, -20, -20, -20, -20, -16, -12,
  82.  -16, -20, -24, -24, -24, -24, -20, -16,
  83.  -16, -20, -24, -24, -24, -24, -20, -16,
  84.  -12, -16, -20, -20, -20, -20, -16, -12,
  85.  -4, -4, -8, -12, -12, -8, -4, -4,
  86.  0, 0, -4, -10, -10, -4, 0, 0};
  87.  
  88. /* King positional bonus in end stage */
  89. static const short KingEnding[64] =
  90. {0, 6, 12, 18, 18, 12, 6, 0,
  91.  6, 12, 18, 24, 24, 18, 12, 6,
  92.  12, 18, 24, 30, 30, 24, 18, 12,
  93.  18, 24, 30, 36, 36, 30, 24, 18,
  94.  18, 24, 30, 36, 36, 30, 24, 18,
  95.  12, 18, 24, 30, 30, 24, 18, 12,
  96.  6, 12, 18, 24, 24, 18, 12, 6,
  97.  0, 6, 12, 18, 18, 12, 6, 0};
  98.  
  99. /* Passed pawn positional bonus */
  100. static const short PassedPawn0[8] =
  101. {0, 60, 80, 120, 200, 360, 600, 800};
  102. static const short PassedPawn1[8] =
  103. {0, 30, 40, 60, 100, 180, 300, 800};
  104. static const short PassedPawn2[8] =
  105. {0, 15, 25, 35, 50, 90, 140, 800};
  106. static const short PassedPawn3[8] =
  107. {0, 5, 10, 15, 20, 30, 140, 800};
  108.  
  109. /* Knight positional bonus */
  110. static const short pknight[64] =
  111. {0, 4, 8, 10, 10, 8, 4, 0,
  112.  4, 8, 16, 20, 20, 16, 8, 4,
  113.  8, 16, 24, 28, 28, 24, 16, 8,
  114.  10, 20, 28, 32, 32, 28, 20, 10,
  115.  10, 20, 28, 32, 32, 28, 20, 10,
  116.  8, 16, 24, 28, 28, 24, 16, 8,
  117.  4, 8, 16, 20, 20, 16, 8, 4,
  118.  0, 4, 8, 10, 10, 8, 4, 0};
  119.  
  120. /* Bishop positional bonus */
  121. static const short pbishop[64] =
  122. {14, 14, 14, 14, 14, 14, 14, 14,
  123.  14, 22, 18, 18, 18, 18, 22, 14,
  124.  14, 18, 22, 22, 22, 22, 18, 14,
  125.  14, 18, 22, 22, 22, 22, 18, 14,
  126.  14, 18, 22, 22, 22, 22, 18, 14,
  127.  14, 18, 22, 22, 22, 22, 18, 14,
  128.  14, 22, 18, 18, 18, 18, 22, 14,
  129.  14, 14, 14, 14, 14, 14, 14, 14};
  130.  
  131. /* Pawn positional bonus */
  132. static const short PawnAdvance[64] =
  133. {0, 0, 0, 0, 0, 0, 0, 0,
  134.  4, 4, 4, 0, 0, 4, 4, 4,
  135.  6, 8, 2, 10, 10, 2, 8, 6,
  136.  6, 8, 12, 16, 16, 12, 8, 6,
  137.  8, 12, 16, 24, 24, 16, 12, 8,
  138.  12, 16, 24, 32, 32, 24, 16, 12,
  139.  12, 16, 24, 32, 32, 24, 16, 12,
  140.  0, 0, 0, 0, 0, 0, 0, 0};
  141.  
  142. short Mwpawn[64], Mbpawn[64], Mknight[2][64], Mbishop[2][64];
  143. static short Mking[2][64], Kfield[2][64];
  144. static short c1, c2, *atk1, *atk2, *PC1, *PC2, atak[2][64];
  145. short emtl[2];
  146. static short PawnBonus, BishopBonus, RookBonus;
  147. static short KNIGHTPOST, KNIGHTSTRONG, BISHOPSTRONG, KATAK;
  148. static short PEDRNK2B, PWEAKH, PADVNCM, PADVNCI, PAWNSHIELD, PDOUBLED, PBLOK;
  149. static short RHOPN, RHOPNX, KHOPN, KHOPNX, KSFTY;
  150. static short ATAKD, HUNGP, HUNGX, KCASTLD, KMOVD, XRAY, PINVAL;
  151. short pscore[2];
  152. short tmtl;
  153.  
  154. #ifdef CACHE
  155. inline void
  156. PutInEETable (short int side,int score)
  157.  
  158. /*
  159.  * Store the current eval position in the transposition table.
  160.  */
  161.  
  162. {
  163.     register struct etable *ptbl;
  164.     ptbl = &etab[side][hashkey % (ETABLE)];
  165.     ptbl->ehashbd = hashbd;
  166.     ptbl->escore[white] = pscore[white];
  167.     ptbl->escore[black] = pscore[black];
  168.     ptbl->hung[white] = hung[white];
  169.     ptbl->hung[black] = hung[black];
  170.     ptbl->score = score;
  171.     bcopy (svalue, &(ptbl->sscore), sizeof (svalue));
  172. #ifndef BAREBONES 
  173.     EADD++;
  174. #endif
  175.     return;
  176. }
  177.  
  178. inline int
  179. CheckEETable (short int side)
  180.  
  181. /* Get an evaluation from the transposition table */
  182. {
  183.     register struct etable *ptbl;
  184.     ptbl = &etab[side][hashkey % (ETABLE)];
  185.     if (hashbd == ptbl->ehashbd) return true;
  186.     return false;
  187. }
  188.  
  189. inline int
  190. ProbeEETable (short int side, short int *score)
  191.  
  192. /* Get an evaluation from the transposition table */
  193. {
  194.     register struct etable *ptbl;
  195.     ptbl = &etab[side][hashkey % (ETABLE)];
  196.     if (hashbd == ptbl->ehashbd)
  197.       {
  198.       pscore[white] = ptbl->escore[white];
  199.       pscore[black] = ptbl->escore[black];
  200.       bcopy (&(ptbl->sscore),svalue, sizeof (svalue));
  201.       *score = ptbl->score;
  202.           hung[white] = ptbl->hung[white];
  203.           hung[black] = ptbl->hung[black];
  204. #ifndef BAREBONES
  205.       EGET++;
  206. #endif
  207.       return true;
  208.       }
  209.     return false;
  210.  
  211. }
  212.  
  213. #endif
  214. /* ............    POSITIONAL EVALUATION ROUTINES    ............ */
  215.  
  216. /*
  217.  * Inputs are:
  218.  * pmtl[side] - value of pawns
  219.  * mtl[side]  - value of all material
  220.  * emtl[side] - vaule of all material - value of pawns - value of king
  221.  * hung[side] - count of hung pieces
  222.  * Tscore[ply] - search tree score for ply
  223.  * ply
  224.  * Pscore[ply] - positional score for ply ply
  225.  * INCscore    - bonus score or penalty for certain positions
  226.  * slk - single lone king flag
  227.  * Sdepth - search goal depth
  228.  * xwndw - evaluation window about alpha/beta
  229.  * EWNDW - second evaluation window about alpha/beta
  230.  * ChkFlag[ply]- checking piece at level ply or 0 if no check
  231.  * PC1[column] - # of my pawns in this column
  232.  * PC2[column] - # of opponents pawns in column
  233.  * PieceCnt[side] - just what it says
  234.  */
  235. inline
  236. int
  237. ScoreKPK (short int side,
  238.       short int winner,
  239.       short int loser,
  240.       short int king1,
  241.       register short int king2,
  242.       register short int sq)
  243.  
  244. /*
  245.  * Score King and Pawns versus King endings.
  246.  */
  247.  
  248. {
  249.     register short s, r;
  250.  
  251.     s = ((PieceCnt[winner] == 1) ? 50 : 120);
  252.     if (winner == white)
  253.       {
  254.       r = row (sq) - ((side == loser) ? 1 : 0);
  255.       if (row (king2) >= r && distance (sq, king2) < 8 - r)
  256.           s += 10 * row (sq);
  257.       else
  258.           s = 500 + 50 * row (sq);
  259.       if (row (sq) < 6)
  260.           sq += 16;
  261.       else if (row (sq) == 6)
  262.           sq += 8;
  263.       }
  264.     else
  265.       {
  266.       r = row (sq) + ((side == loser) ? 1 : 0);
  267.       if (row (king2) <= r && distance (sq, king2) < r + 1)
  268.           s += 10 * (7 - row (sq));
  269.       else
  270.           s = 500 + 50 * (7 - row (sq));
  271.       if (row (sq) > 1)
  272.           sq -= 16;
  273.       else if (row (sq) == 1)
  274.           sq -= 8;
  275.       }
  276.     s += 8 * (taxicab (king2, sq) - taxicab (king1, sq));
  277.     return (s);
  278. }
  279.  
  280. short 
  281. kpkwv_ (short *pf, short *pr, short *wf, short *wr, short *
  282.     bf, short *br)
  283. {
  284.  
  285.   /*
  286.    *  Don Beal's routine, which was originally in Fortran.  See AICC 2
  287.    */
  288.  
  289.   const short c__8 = 8;
  290.   const short c__5 = 5;
  291.   const short c__3 = 3;
  292.   /* System generated locals */
  293.   short ret_val, i__1, i__2;
  294.  
  295.   /* Local variables */
  296.   static short wbdd, mbpf, nbpf, blpu;
  297.   short dist_ (short *, short *, short *, short *);
  298.   static short brpu, mwpf, wlpu, wrpu, blpuu, brpuu, wlpuu, wrpuu, md,
  299.     bq, blpuuu, brpuuu, bsd, tbf, sgf, bpp, sdr, sgr, wsd, wsg, ppr, wpp;
  300.  
  301.  
  302.   ret_val = 1;
  303.   if (*pr == 2) { ppr = 3; }
  304.   if (*pf != 1) { goto L2; }
  305.   if (*bf != 3) { goto L1; }
  306.   if (*pr == 7 && *wf == 1 && *wr == 8 && *br > 6) { goto L98; }
  307.   if (*pr == 6 && *wf < 4 && *wr == 6 && *br == 8) { goto L99; }
  308. L1:
  309.   if (*bf == 1 && *br > *pr) { goto L98; }
  310.   if (*pr == 7 && *bf > 2) { goto L99; }
  311.   if (*bf <= 3 && *br - ppr > 1) { goto L98; }
  312.   if (*wf == 1 && *bf == 3 && *wr - *pr == 1 && *br - *pr == 1) { goto L98; }
  313. L2:
  314.   bq = dist_ (bf, br, pf, &c__8);
  315.   if (bq > 8 - ppr) { goto L99; }
  316.   mbpf = *bf - *pf;
  317.   if (mbpf < 0) { mbpf = -mbpf; }
  318.   bpp = dist_ (bf, br, pf, &ppr);
  319.   wpp = dist_ (wf, wr, pf, &ppr);
  320.   if (bpp - wpp < -1 && *br - *pr != mbpf) { goto L98; }
  321.   if (*pf == 1 && *pr <= 3 && *wf <= 2 && *wr == 8 && *bf == 4 && *br >= 7) { goto L99; }
  322.   if (*pf != 2 || *pr != 6 || *bf != 1 || *br != 8) { goto L3; }
  323.   if (*wf <= 3 && *wr == 6) { goto L98; }
  324.   if (*wf == 4 && *wr == 8) { goto L98; }
  325. L3:
  326.   if (*pr != 7) { goto L4; }
  327.   if (*wr < 8 && wpp == 2 && bq == 0) { goto L99; }
  328.   if (*wr == 6 && *wf == *pf && bq == 0) { goto L99; }
  329.   if (*wr >= 6 && wpp <= 2 && bq != 0) { goto L99; }
  330. L4:
  331.   i__1 = *pf - 1;
  332.   i__2 = *pr + 2;
  333.   blpuu = dist_ (bf, br, &i__1, &i__2);
  334.   i__1 = *br - 2;
  335.   wbdd = dist_ (wf, wr, bf, &i__1);
  336.   i__1 = *pf + 1;
  337.   i__2 = *pr + 2;
  338.   brpuu = dist_ (bf, br, &i__1, &i__2);
  339.   if (*pr != 6) { goto L6; }
  340.   i__1 = *pf + 1;
  341.   i__2 = *pf + 1;
  342.   if (dist_ (bf, br, &i__1, pr) > 1 && brpuu > dist_ (wf, wr, &i__2, pr)) { goto L99; }
  343.   if (*pf == 1) { goto L5; }
  344.   i__1 = *pf - 1;
  345.   if (blpuu > dist_ (wf, wr, &i__1, pr)) { goto L99; }
  346.   if (*br == 8 && mbpf == 1 && wbdd == 1) { goto L99; }
  347.   if (*br > 6 && nbpf == 2 && dist_ (wf, wr, bf, &c__5) <= 1) { goto L99; }
  348.   goto L6;
  349. L5:
  350.   if (*wf == 1 && *wr == 8 && *bf == 2 && *br == 6) { goto L98; }
  351. L6:
  352.   mwpf = *wf - *pf;
  353.   if (mwpf < 0) { mwpf = -mwpf; }
  354.   if (*pr >= 5 && mwpf == 2 && *wr == *pr && *bf == *wf && *br - *pr == 2) { goto L99; }
  355.   i__1 = *pf + 1;
  356.   i__2 = *pr + 1;
  357.   brpu = dist_ (bf, br, &i__1, &i__2);
  358.   i__1 = *pf + 1;
  359.   i__2 = *pr + 1;
  360.   wrpu = dist_ (wf, wr, &i__1, &i__2);
  361.   i__1 = *pf - 1;
  362.   i__2 = *pr + 1;
  363.   blpu = dist_ (bf, br, &i__1, &i__2);
  364.   i__1 = *pf - 1;
  365.   i__2 = *pr + 1;
  366.   wlpu = dist_ (wf, wr, &i__1, &i__2);
  367.   if (*pf == 1 || *pr != 5) { goto L7; }
  368.   if (mwpf <= 1 && *wr - *pr == 1) { goto L99; }
  369.   if (wrpu == 1 && brpu > 1) { goto L99; }
  370.   if (*wr >= 4 && *bf == *wf && *br - *pr >= 2 && mbpf == 3) { goto L99; }
  371.   if (wlpu == 1 && blpu > 1) { goto L99; }
  372. L7:
  373.   i__1 = *br + 2;
  374.   if (*pr == 2 && *br == 3 && mbpf > 1 && dist_ (wf, wr, bf, &i__1) <= 1) { goto L99; }
  375.   if (*wr - *pr == 2 && *br == *pr && mbpf == 1 && mwpf > 1 && (*wf - *pf) *
  376.       (*bf - *pf) > 0) { goto L98; }
  377.   if (*pf == 1 && *wf == 1 && *wr == *br && *bf > 3) { goto L99; }
  378.   sgf = *pf - 1;
  379.   if (*wf >= *pf) { sgf = *pf + 1; }
  380.   sgr = *wr - (mwpf - 1);
  381.   if (mwpf == 0 && *wr > *br) { sgr = *wr - 1; }
  382.   wsg = dist_ (wf, wr, &sgf, &sgr);
  383.   if (*wr - *pr - mwpf > 0 && *wr - *br >= -1 && bpp - (wsg + (sgr - ppr))
  384.       >= -1 && dist_ (bf, br, &sgf, &sgr) > wsg) { goto L99; }
  385.   md = mbpf - mwpf;
  386.   if (*pf != 1 || *bf <= 3) { goto L8; }
  387.   sdr = *br + (*bf - 3);
  388.   if (sdr > 8) { sdr = 8; }
  389.   if (*wr > *br + 1) { sdr = *br; }
  390.   if (sdr <= ppr) { goto L8; }
  391.   wsd = dist_ (wf, wr, &c__3, &sdr);
  392.   bsd = dist_ (bf, br, &c__3, &sdr);
  393.   if (bsd - wsd < -1) { goto L98; }
  394.   if (bsd <= wsd && md <= 0) { goto L98; }
  395. L8:
  396.   i__1 = *pf + 1;
  397.   i__2 = *pr + 3;
  398.   brpuuu = dist_ (bf, br, &i__1, &i__2);
  399.   if (brpu > wrpu && brpuuu > wrpu && *pr - *wr != *pf - *wf) { goto L99; }
  400.   if (brpuuu == 0 && wrpu == 1) { goto L99; }
  401.   i__1 = *pf - 1;
  402.   i__2 = *pr + 3;
  403.   blpuuu = dist_ (bf, br, &i__1, &i__2);
  404.   if (*pf == 1) { goto L9; }
  405.   if (blpu > wlpu && blpuuu > wlpu && *pr - *wr != *wf - *pf) { goto L99; }
  406.   if (blpuuu == 0 && wlpu == 1) { goto L99; }
  407. L9:
  408.   i__1 = *pf + 1;
  409.   i__2 = *pr + 2;
  410.   wrpuu = dist_ (wf, wr, &i__1, &i__2);
  411.   if (brpuu > wrpuu) { goto L99; }
  412.   i__1 = *pf - 1;
  413.   i__2 = *pr + 2;
  414.   wlpuu = dist_ (wf, wr, &i__1, &i__2);
  415.   if (*pf > 1 && blpuu > wlpuu) { goto L99; }
  416.   if (*br != *pr) { goto L10; }
  417.   if (mwpf <= 2 && *wr - *pr == -1 && mbpf != 2) { goto L99; }
  418.   i__1 = *bf - 1;
  419.   i__2 = *br + 2;
  420.   if (dist_ (wf, wr, &i__1, &i__2) <= 1 && *bf - *pf > 1) { goto L99; }
  421.   i__1 = *bf + 1;
  422.   i__2 = *br + 2;
  423.   if (dist_ (wf, wr, &i__1, &i__2) <= 1 && *bf - *pf < -1) { goto L99; }
  424. L10:
  425.   if (*pf == 1) { goto L11; }
  426.   i__1 = *pr - 1;
  427.   if (*br == *pr && mbpf > 1 && dist_ (wf, wr, pf, &i__1) <= 1) { goto L99; }
  428.   if (*br - *pr >= 3 && wbdd == 1) { goto L99; }
  429.   if (*wr - *pr >= 2 && *wr < *br && md >= 0) { goto L99; }
  430.   if (mwpf <= 2 && *wr - *pr >= 3 && *bf != *pf && *wr - *br <= 1) { goto L99; }
  431.   if (*wr >= *pr && *br - *pr >= 5 && mbpf >= 3 && md >= -1 && ppr == 3) { goto L99; }
  432.   if (md >= -1 && *pr == 2 && *br == 8) { goto L99; }
  433. L11:
  434.   tbf = *bf - 1;
  435.   if (*pf > *bf) { tbf = *bf + 1; }
  436.   i__1 = *wr + 2;
  437.   if (mbpf > 1 && *br == ppr && dist_ (wf, wr, &tbf, &i__1) <= 1) { goto L99; }
  438.   i__1 = *pf + 2;
  439.   i__2 = *pr - 1;
  440.   if (*br == *pr && *bf - *pf == -2 && dist_ (wf, wr, &i__1, &i__2) <= 1) { goto L99; }
  441.   i__1 = *pf - 2;
  442.   i__2 = *pr - 1;
  443.   if (*pf > 2 && *br == *pr && *bf - *pf == 2 && dist_ (wf, wr, &i__1, &i__2) <= 1) { goto L99; }
  444. L98:
  445.   ret_val = 0;
  446. L99:
  447.   return ret_val;
  448. }                /* kpkwv_ */
  449.  
  450. short 
  451. kpkbv_ (short *pf, short *pr, short *wf, short *wr, short *
  452.     bf, short *br)
  453. {
  454.   /* Initialized data */
  455.  
  456.   static short incf[8] =
  457.   {0, 1, 1, 1, 0, -1, -1, -1};
  458.   static short incr[8] =
  459.   {1, 1, 0, -1, -1, -1, 0, 1};
  460.  
  461.   /* System generated locals */
  462.   short ret_val;
  463.  
  464.   /* Local variables */
  465.   short dist_ (short *, short *, short *, short *);
  466.   static short i;
  467.   short kpkwv_ (short *, short *, short *, short *, short
  468.          *, short *);
  469.   static short nm, nbf, nbr;
  470.  
  471.   ret_val = 0;
  472.   nm = 0;
  473.   for (i = 1; i <= 8; ++i)
  474.     {
  475.       nbf = *bf + incf[i - 1];
  476.       if (nbf < 1 || nbf > 8) { goto L1; }
  477.       nbr = *br + incr[i - 1];
  478.       if (nbr < 1 || nbr > 8) { goto L1; }
  479.       if (dist_ (&nbf, &nbr, wf, wr) < 2) { goto L1; }
  480.       if (nbf == *pf && nbr == *pr) { goto L2; }
  481.       if (nbr == *pr + 1 && (nbf == *pf - 1 || nbf == *pf + 1)) { goto L1; }
  482.       ++nm;
  483.       if (kpkwv_ (pf, pr, wf, wr, &nbf, &nbr) == 0) { goto L2; }
  484.     L1:
  485.       ;
  486.     }
  487.   if (nm > 0) { ret_val = -1; }
  488. L2:
  489.   return ret_val;
  490. }                /* kpkbv_ */
  491.  
  492. short 
  493. dist_ (short *f1, short *r1, short *f2, short *r2)
  494. {
  495.   /* System generated locals */
  496.   short ret_val;
  497.  
  498.   /* Local variables */
  499.   static short fd, rd;
  500.  
  501.   fd = *f2 - *f1;
  502.   if (fd < 0)
  503.     {
  504.       fd = -fd;
  505.     }
  506.   rd = *r2 - *r1;
  507.   if (rd < 0)
  508.     {
  509.       rd = -rd;
  510.     }
  511.   ret_val = fd;
  512.   if (rd > ret_val)
  513.     {
  514.       ret_val = rd;
  515.     }
  516.   return ret_val;
  517. }                /* dist_ */
  518.  
  519. inline
  520. int
  521. ScoreK1PK (short int side,
  522.        short int winner,
  523.        short int loser,
  524.        short int king1,
  525.        register short int king2,
  526.        register short int sq)
  527.  
  528.      /*
  529.       *  We call Don Beal's routine with the necessary parameters and determine
  530.       *  win/draw/loss.  Then we compute the real evaluation which is +-500 for
  531.       *  a win/loss and 10 for a draw, plus some points to lead the computer to
  532.       *  a decisive winning/drawing line.
  533.       */
  534.  
  535. {
  536.   short s, win, sqc, sqr, k1c, k1r, k2c, k2r;
  537.   const int drawn = 10, won = 500;
  538.  
  539.   sqc = column (sq) + 1;
  540.   sqr = row (sq) + 1;
  541.   k1c = column (king1) + 1;
  542.   k1r = row (king1) + 1;
  543.   k2c = column (king2) + 1;
  544.   k2r = row (king2) + 1;
  545.   if (winner == black)
  546.     {
  547.       sqr = 9 - sqr;
  548.       k1r = 9 - k1r;
  549.       k2r = 9 - k2r;
  550.     }
  551.   if (sqc > 4)
  552.     {
  553.       sqc = 9 - sqc;
  554.       k1c = 9 - k1c;
  555.       k2c = 9 - k2c;
  556.     }
  557.  
  558.   if (side == winner)
  559.     win = kpkwv_ (&sqc, &sqr, &k1c, &k1r, &k2c, &k2r);
  560.   else
  561.     win = kpkbv_ (&sqc, &sqr, &k1c, &k1r, &k2c, &k2r);
  562.  
  563.   if (!win)
  564.     return drawn + 5 * distance (sq, king2);
  565.   else
  566.     return won + 50 * (sqr - 2);
  567.  
  568. }
  569.  
  570. inline
  571. int
  572. ScoreKBNK (short int winner, short int king1, short int king2)
  573.  
  574.  
  575. /*
  576.  * Score King+Bishop+Knight versus King endings. This doesn't work all that
  577.  * well but it's better than nothing.
  578.  */
  579.  
  580. {
  581.     register short s, sq, KBNKsq = 0;
  582.  
  583.     for (sq = 0; sq < 64; sq++)
  584.     if (board[sq] == bishop)
  585.         KBNKsq = (((row (sq) % 2) == (column (sq) % 2)) ? 0 : 7);
  586.  
  587.     s = emtl[winner] - 300;
  588.     s += ((KBNKsq == 0) ? KBNK[king2] : KBNK[locn (row (king2), 7 - column (king2))]);
  589.     s -= ((taxicab (king1, king2) + distance (PieceList[winner][1], king2) + distance (PieceList[winner][2], king2)));
  590.     return (s);
  591. }
  592.  
  593. inline
  594. short int
  595. ScoreLoneKing (short int side)
  596.  
  597.      /*
  598.       * Static evaluation when loser has only a king and winner has no pawns or no
  599.       * pieces.
  600.       */
  601.  
  602. {
  603.   register short winner, loser, king1, king2, s, i;
  604.  
  605.   if (mtl[white] == valueK && mtl[black] == valueK)
  606.     return 0;
  607.   UpdateWeights ();
  608.   winner = ((mtl[white] > mtl[black]) ? white : black);
  609.   loser = winner ^ 1;
  610.   king1 = PieceList[winner][0];
  611.   king2 = PieceList[loser][0];
  612.  
  613.   s = 0;
  614.  
  615.   if (pmtl[winner] == 0)
  616.     {
  617.       if (emtl[winner] == valueB + valueN)
  618.     s = ScoreKBNK (winner, king1, king2);
  619.       else if (emtl[winner] == valueN + valueN)
  620.     s = 0;
  621.       else
  622.     s = 500 + emtl[winner] - DyingKing[king2] - 2 * distance (king1, king2);
  623.     }
  624.   else
  625.     {
  626.       if (pmtl[winner] == valueP)
  627.     s = ScoreK1PK (side, winner, loser, king1, king2, PieceList[winner][1]);
  628.       else
  629.     for (i = 1; i <= PieceCnt[winner]; i++)
  630.       s += ScoreKPK (side, winner, loser, king1, king2, PieceList[winner][i]);
  631.     }
  632.   return ((side == winner) ? s : -s);
  633. }
  634.  
  635.  
  636. int
  637. evaluate (register short int side,
  638.       register short int ply,
  639.       register short int alpha,
  640.       register short int beta,
  641.       short int INCscore,
  642.       short int *InChk)    /* output Check flag */
  643.  
  644. /*
  645.  * Compute an estimate of the score by adding the positional score from the
  646.  * previous ply to the material difference. If this score falls inside a
  647.  * window which is 180 points wider than the alpha-beta window (or within a
  648.  * 50 point window during quiescence search) call ScorePosition() to
  649.  * determine a score, otherwise return the estimated score. If one side has
  650.  * only a king and the other either has no pawns or no pieces then the
  651.  * function ScoreLoneKing() is called.
  652.  */
  653.  
  654. {
  655.     register short evflag, xside;
  656.     register short int slk;
  657.     short s;
  658.  
  659.     xside = side ^ 1;
  660.     s = -Pscore[ply - 1] + mtl[side] - mtl[xside] - INCscore;
  661.     hung[white] = hung[black] = 0;
  662.     slk = ((mtl[white] == valueK && (pmtl[black] == 0 || emtl[black] == 0)) ||
  663.       (mtl[black] == valueK && (pmtl[white] == 0 || emtl[white] == 0)));
  664.  
  665.           /* should we use the estimete or score the position */
  666.     if ( ply == 1 ||
  667. #ifdef CACHE
  668.         (CheckEETable (side)) ||
  669. #endif
  670.     slk || 
  671.     (Sdepth ==  ply) || 
  672.         (ply > Sdepth && (s >= (alpha - 30) && s <= (beta + 30)) ))
  673.     
  674.       {
  675.       /* score the position */
  676.       ataks (side, atak[side]);
  677.       if (Anyatak (side, PieceList[xside][0])){
  678.       ataks (xside, atak[xside]);
  679.       *InChk = Anyatak (xside, PieceList[side][0]);
  680.           return (10001 - ply);
  681.       }
  682.       ataks (xside, atak[xside]);
  683.       *InChk = Anyatak (xside, PieceList[side][0]);
  684. #ifndef BAREBONES 
  685.       EvalNodes++;
  686. #endif
  687.     if(ply>4)PUTVAR=true;
  688.           s = ScorePosition (side);
  689.     PUTVAR=false;
  690.       }
  691.     else
  692.       {
  693.       /* use the estimate but look at check and slk */
  694.       *InChk = SqAtakd (PieceList[side][0], xside);
  695.       if (SqAtakd (PieceList[xside][0], side)){
  696.           return (10001 - ply);
  697.       }
  698.       if (slk)
  699.           s = ScoreLoneKing (side);
  700.       }
  701.  
  702.     Pscore[ply] = s - mtl[side] + mtl[xside];
  703.     ChkFlag[ply - 1] = ((*InChk) ? Pindex[TOsquare] : 0);
  704.     return (s);
  705. }
  706.  
  707. inline
  708. int
  709. BRscan (register short int sq, short int *mob)
  710.  
  711. /*
  712.  * Find Bishop and Rook mobility, XRAY attacks, and pins. Increment the
  713.  * hung[] array if a pin is found.
  714.  */
  715. {
  716.     register unsigned char *ppos, *pdir;
  717.     register short s, mobx;
  718.     register short u, pin;
  719.     short piece, *Kf;
  720.     mobx = s = 0;
  721.     Kf = Kfield[c1];
  722.     piece = board[sq];
  723.     ppos = nextpos[piece][sq];
  724.     pdir = nextdir[piece][sq];
  725.     u = ppos[sq];
  726.     pin = -1;            /* start new direction */
  727.     do
  728.       {
  729.       s += Kf[u];
  730.       if (color[u] == neutral)
  731.         {
  732.         mobx++;
  733.         if (ppos[u] == pdir[u])
  734.             pin = -1;    /* oops new direction */
  735.         u = ppos[u];
  736.         }
  737.       else if (pin < 0)
  738.         {
  739.         if (board[u] == pawn || board[u] == king)
  740.             u = pdir[u];
  741.         else
  742.           {
  743.               if (ppos[u] != pdir[u])
  744.               pin = u;    /* not on the edge and on to find a pin */
  745.               u = ppos[u];
  746.           }
  747.         }
  748.       else
  749.         {
  750.         if (color[u] == c2 && (board[u] > piece || atk2[u] == 0))
  751.           {
  752.               if (color[pin] == c2)
  753.             {
  754.                 s += PINVAL;
  755.                 if (atk2[pin] == 0 || atk1[pin] > control[board[pin]] + 1)
  756.                 ++hung[c2];
  757.             }
  758.               else
  759.               s += XRAY;
  760.           }
  761.         pin = -1;    /* new direction */
  762.         u = pdir[u];
  763.         }
  764.       }
  765.     while (u != sq);
  766.     *mob = mobx;
  767.     return s;
  768. }
  769.  
  770. inline
  771. short int
  772. KingScan (register short int sq)
  773.  
  774. /*
  775.  * Assign penalties if king can be threatened by checks, if squares near the
  776.  * king are controlled by the enemy (especially the queen), or if there are
  777.  * no pawns near the king. The following must be true: board[sq] == king c1
  778.  * == color[sq] c2 == otherside[c1]
  779.  */
  780.  
  781. #define ScoreThreat \
  782.     if (color[u] != c2)\
  783.       if (atk1[u] == 0 || (atk2[u] & 0xFF) > 1) ++cnt;\
  784.       else s -= 3
  785.  
  786. {
  787.     register short cnt;
  788.     register unsigned char *ppos, *pdir;
  789.     register short int s;
  790.     register short u;
  791.     short int ok;
  792.  
  793.     s = 0;
  794.     cnt = 0;
  795.     if (HasBishop[c2] || HasQueen[c2])
  796.       {
  797.       ppos = nextpos[bishop][sq];
  798.       pdir = nextdir[bishop][sq];
  799.       u = ppos[sq];
  800.       do
  801.         {
  802.         if (atk2[u] & ctlBQ)
  803.             ScoreThreat;
  804.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  805.         }
  806.       while (u != sq);
  807.       }
  808.     if (HasRook[c2] || HasQueen[c2])
  809.       {
  810.       ppos = nextpos[rook][sq];
  811.       pdir = nextdir[rook][sq];
  812.       u = ppos[sq];
  813.       do
  814.         {
  815.         if (atk2[u] & ctlRQ)
  816.             ScoreThreat;
  817.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  818.         }
  819.       while (u != sq);
  820.       }
  821.     if (HasKnight[c2])
  822.       {
  823.       pdir = nextdir[knight][sq];
  824.       u = pdir[sq];
  825.       do
  826.         {
  827.         if (atk2[u] & ctlNN)
  828.             ScoreThreat;
  829.         u = pdir[u];
  830.         }
  831.       while (u != sq);
  832.       }
  833.     s += (KSFTY * KTHRT[cnt]) / 16;
  834.  
  835.     cnt = 0;
  836.     ok = false;
  837.     pdir = nextpos[king][sq];
  838.     u = pdir[sq];
  839.     do
  840.       {
  841.       if (board[u] == pawn)
  842.           ok = true;
  843.       if (atk2[u] > atk1[u])
  844.         {
  845.         ++cnt;
  846.         if (atk2[u] & ctlQ)
  847.             if (atk2[u] > ctlQ + 1 && atk1[u] < ctlQ)
  848.             s -= 4 * KSFTY;
  849.         }
  850.       u = pdir[u];
  851.       }
  852.     while (u != sq);
  853.     if (!ok)
  854.     s -= KSFTY;
  855.     if (cnt > 1)
  856.     s -= (KSFTY);
  857.     return (s);
  858. }
  859.  
  860. inline
  861. int
  862. trapped (register short int sq)
  863.  
  864. /*
  865.  * See if the attacked piece has unattacked squares to move to. The following
  866.  * must be true: c1 == color[sq] c2 == otherside[c1]
  867.  */
  868.  
  869. {
  870.     register short u;
  871.     register unsigned char *ppos, *pdir;
  872.     register short int piece;
  873.  
  874.     piece = board[sq];
  875.     ppos = nextpos[ptype[c1][piece]][sq];
  876.     pdir = nextdir[ptype[c1][piece]][sq];
  877.     if (piece == pawn)
  878.       {
  879.       u = ppos[sq];        /* follow no captures thread */
  880.       if (color[u] == neutral)
  881.         {
  882.         if (atk1[u] >= atk2[u])
  883.             return (false);
  884.         if (atk2[u] < ctlP)
  885.           {
  886.               u = ppos[u];
  887.               if (color[u] == neutral && atk1[u] >= atk2[u])
  888.               return (false);
  889.           }
  890.         }
  891.       u = pdir[sq];        /* follow captures thread */
  892.       if (color[u] == c2)
  893.           return (false);
  894.       u = pdir[u];
  895.       if (color[u] == c2)
  896.           return (false);
  897.       }
  898.     else
  899.       {
  900.       u = ppos[sq];
  901.       do
  902.         {
  903.         if (color[u] != c1)
  904.             if (atk2[u] == 0 || board[u] >= piece)
  905.             return (false);
  906.         u = ((color[u] == neutral) ? ppos[u] : pdir[u]);
  907.         }
  908.       while (u != sq);
  909.       }
  910.     return (true);
  911. }
  912.  
  913.  
  914. static inline int
  915. PawnValue (register short int sq, short int side)
  916. /*
  917.  * Calculate the positional value for a pawn on 'sq'.
  918.  */
  919.  
  920. {
  921.     register short fyle, rank;
  922.     register short j, s, a1, a2, in_square, r, e;
  923.  
  924.     a1 = (atk1[sq] & 0x4FFF);
  925.     a2 = (atk2[sq] & 0x4FFF);
  926.     rank = row (sq);
  927.     fyle = column (sq);
  928.     s = 0;
  929.     if (c1 == white)
  930.       {
  931.       s = Mwpawn[sq];
  932.       if ((sq == 11 && color[19] != neutral)
  933.           || (sq == 12 && color[20] != neutral))
  934.           s += PEDRNK2B;
  935.       if ((fyle == 0 || PC1[fyle - 1] == 0)
  936.           && (fyle == 7 || PC1[fyle + 1] == 0))
  937.           s += ISOLANI[fyle];
  938.       else if (PC1[fyle] > 1)
  939.           s += PDOUBLED;
  940.       if (a1 < ctlP && atk1[sq + 8] < ctlP)
  941.         {
  942.         s += BACKWARD[a2 & 0xFF];
  943.         if (PC2[fyle] == 0)
  944.             s += PWEAKH;
  945.         if (color[sq + 8] != neutral)
  946.             s += PBLOK;
  947.         }
  948.       if (PC2[fyle] == 0)
  949.         {
  950.         if (side == black)
  951.             r = rank - 1;
  952.         else
  953.             r = rank;
  954.         in_square = (row (bking) >= r && distance (sq, bking) < 8 - r);
  955.         e = (a2 == 0 || side == white)? 0:1;
  956.         for (j = sq + 8; j < 64; j += 8)
  957.             if (atk2[j] >= ctlP)
  958.               {
  959.               e = 2;
  960.               break;
  961.               }
  962.             else if (atk2[j] > 0 || color[j] != neutral)
  963.             e = 1;
  964.         if (e == 2)
  965.             s += (stage * PassedPawn3[rank]) / 10;
  966.         else if (in_square || e == 1)
  967.             s += (stage * PassedPawn2[rank]) / 10;
  968.         else if (emtl[black] > 0)
  969.             s += (stage * PassedPawn1[rank]) / 10;
  970.         else
  971.             s += PassedPawn0[rank];
  972.         }
  973.       }
  974.     else if (c1 == black)
  975.       {
  976.       s = Mbpawn[sq];
  977.       if ((sq == 51 && color[43] != neutral)
  978.           || (sq == 52 && color[44] != neutral))
  979.           s += PEDRNK2B;
  980.       if ((fyle == 0 || PC1[fyle - 1] == 0) &&
  981.           (fyle == 7 || PC1[fyle + 1] == 0))
  982.           s += ISOLANI[fyle];
  983.       else if (PC1[fyle] > 1)
  984.           s += PDOUBLED;
  985.       if (a1 < ctlP && atk1[sq - 8] < ctlP)
  986.         {
  987.         s += BACKWARD[a2 & 0xFF];
  988.         if (PC2[fyle] == 0)
  989.             s += PWEAKH;
  990.         if (color[sq - 8] != neutral)
  991.             s += PBLOK;
  992.         }
  993.       if (PC2[fyle] == 0)
  994.         {
  995.         r = rank + (side == white)?1:0;
  996.         in_square = (row (wking) <= r && distance (sq, wking) < r + 1);
  997.         e = (a2 == 0 || side == black)?0:1;
  998.         for (j = sq - 8; j >= 0; j -= 8)
  999.             if (atk2[j] >= ctlP)
  1000.               {
  1001.               e = 2;
  1002.               break;
  1003.               }
  1004.             else if (atk2[j] > 0 || color[j] != neutral)
  1005.             e = 1;
  1006.         if (e == 2)
  1007.             s += (stage * PassedPawn3[7 - rank]) / 10;
  1008.         else if (in_square || e == 1)
  1009.             s += (stage * PassedPawn2[7 - rank]) / 10;
  1010.         else if (emtl[white] > 0)
  1011.             s += (stage * PassedPawn1[7 - rank]) / 10;
  1012.         else
  1013.             s += PassedPawn0[7 - rank];
  1014.         }
  1015.       }
  1016.     if (a2 > 0)
  1017.       {
  1018.       if (a1 == 0 || a2 > ctlP + 1)
  1019.         {
  1020.         s += HUNGP;
  1021.         if (trapped (sq))
  1022.             hung[c1] += 2;
  1023.         hung[c1]++;
  1024.         }
  1025.       else if (a2 > a1)
  1026.           s += ATAKD;
  1027.       }
  1028.     return (s);
  1029. }
  1030.  
  1031. inline
  1032. int
  1033. KnightValue (register short int sq, short int side)
  1034.  
  1035. /*
  1036.  * Calculate the positional value for a knight on 'sq'.
  1037.  */
  1038.  
  1039. {
  1040.     register short s, a2, a1;
  1041.  
  1042.     s = Mknight[c1][sq];
  1043.     a2 = (atk2[sq] & 0x4FFF);
  1044.     if (a2 > 0)
  1045.       {
  1046.       a1 = (atk1[sq] & 0x4FFF);
  1047.       if (a1 == 0 || a2 > ctlBN + 1)
  1048.         {
  1049.         s += HUNGP;
  1050.         if (trapped (sq))
  1051.             hung[c1] += 2;
  1052.         hung[c1]++;
  1053.         }
  1054.       else if (a2 >= ctlBN || a1 < ctlP)
  1055.           s += ATAKD;
  1056.       }
  1057.     return (s);
  1058. }
  1059.  
  1060. inline
  1061. int
  1062. BishopValue (register short int sq, short int side)
  1063.  
  1064. /*
  1065.  * Calculate the positional value for a bishop on 'sq'.
  1066.  */
  1067.  
  1068. {
  1069.     register short s;
  1070.     register short a2, a1;
  1071.     short mob;
  1072.  
  1073.     s = Mbishop[c1][sq];
  1074.     s += BRscan (sq, &mob);
  1075.     s += BMBLTY[mob];
  1076.     a2 = (atk2[sq] & 0x4FFF);
  1077.     if (a2 > 0)
  1078.       {
  1079.       a1 = (atk1[sq] & 0x4FFF);
  1080.       if (a1 == 0 || a2 > ctlBN + 1)
  1081.         {
  1082.         s += HUNGP;
  1083.         if (trapped (sq))
  1084.             hung[c1] += 2;
  1085.         hung[c1]++;
  1086.         }
  1087.       else if (a2 >= ctlBN || a1 < ctlP)
  1088.           s += ATAKD;
  1089.       }
  1090.     return (s);
  1091. }
  1092.  
  1093. inline
  1094. int
  1095. RookValue (register short int sq, short int side)
  1096.  
  1097. /*
  1098.  * Calculate the positional value for a rook on 'sq'.
  1099.  */
  1100.  
  1101. {
  1102.     register short s;
  1103.     register short fyle, a2, a1;
  1104.     short mob;
  1105.  
  1106.     s = RookBonus;
  1107.     s += BRscan (sq, &mob);
  1108.     s += RMBLTY[mob];
  1109.     fyle = column (sq);
  1110.     if (PC1[fyle] == 0)
  1111.     { s += RHOPN;
  1112.             if (PC2[fyle] == 0)
  1113.             s += RHOPNX;
  1114.         }
  1115.     if (pmtl[c2] > 100 && row (sq) == rank7[c1])
  1116.     s += 10;
  1117.     if (stage > 2)
  1118.     s += 14 - taxicab (sq, EnemyKing);
  1119.     a2 = (atk2[sq] & 0x4FFF);
  1120.     if (a2 > 0)
  1121.       {
  1122.       a1 = (atk1[sq] & 0x4FFF);
  1123.       if (a1 == 0 || a2 > ctlR + 1)
  1124.         {
  1125.         s += HUNGP;
  1126.         if (trapped (sq))
  1127.             hung[c1] += 2;
  1128.         hung[c1]++;
  1129.         }
  1130.       else if (a2 >= ctlR || a1 < ctlP)
  1131.           s += ATAKD;
  1132.       }
  1133.     return (s);
  1134. }
  1135.  
  1136. inline
  1137. int
  1138. QueenValue (register short int sq, short int side)
  1139.  
  1140. /*
  1141.  * Calculate the positional value for a queen on 'sq'.
  1142.  */
  1143.  
  1144. {
  1145.     register short s, a2, a1;
  1146.  
  1147.     s = ((distance (sq, EnemyKing) < 3) ? 12 : 0);
  1148.     if (stage > 2)
  1149.     s += 14 - taxicab (sq, EnemyKing);
  1150.     a2 = (atk2[sq] & 0x4FFF);
  1151.     if (a2 > 0)
  1152.       {
  1153.       a1 = (atk1[sq] & 0x4FFF);
  1154.       if (a1 == 0 || a2 > ctlQ + 1)
  1155.         {
  1156.         s += HUNGP;
  1157.         if (trapped (sq))
  1158.             hung[c1] += 2;
  1159.         hung[c1]++;
  1160.         }
  1161.       else if (a2 >= ctlQ || a1 < ctlP)
  1162.           s += ATAKD;
  1163.       }
  1164.     return (s);
  1165. }
  1166.  
  1167. inline
  1168. int
  1169. KingValue (register short int sq, short int side)
  1170.  
  1171. /*
  1172.  * Calculate the positional value for a king on 'sq'.
  1173.  */
  1174.  
  1175. {
  1176.     register short s;
  1177.     register short fyle;
  1178.     short int a2, a1;
  1179.     s = (emtl[side ^ 1] > KINGPOSLIMIT) ? Mking[c1][sq] : Mking[c1][sq] / 2;
  1180.     if (KSFTY > 0)
  1181.     if (Developed[c2] || stage > 0)
  1182.         s += KingScan (sq);
  1183.     if (castld[c1])
  1184.     s += KCASTLD;
  1185.     else if (Mvboard[kingP[c1]])
  1186.     s += KMOVD;
  1187.  
  1188.     fyle = column (sq);
  1189.     if (PC1[fyle] == 0)
  1190.     s += KHOPN;
  1191.     if (PC2[fyle] == 0)
  1192.     s += KHOPNX;
  1193.     switch (fyle)
  1194.       {
  1195.       case 5:
  1196.       if (PC1[7] == 0)
  1197.           s += KHOPN;
  1198.       if (PC2[7] == 0)
  1199.           s += KHOPNX;
  1200.       /* Fall through */
  1201.       case 4:
  1202.       case 6:
  1203.       case 0:
  1204.       if (PC1[fyle + 1] == 0)
  1205.           s += KHOPN;
  1206.       if (PC2[fyle + 1] == 0)
  1207.           s += KHOPNX;
  1208.       break;
  1209.       case 2:
  1210.       if (PC1[0] == 0)
  1211.           s += KHOPN;
  1212.       if (PC2[0] == 0)
  1213.           s += KHOPNX;
  1214.       /* Fall through */
  1215.       case 3:
  1216.       case 1:
  1217.       case 7:
  1218.       if (PC1[fyle - 1] == 0)
  1219.           s += KHOPN;
  1220.       if (PC2[fyle - 1] == 0)
  1221.           s += KHOPNX;
  1222.       break;
  1223.       default:
  1224.       /* Impossible! */
  1225.       break;
  1226.       }
  1227.  
  1228.     a2 = (atk2[sq] & 0x4FFF);
  1229.     if (a2 > 0)
  1230.       {
  1231.       a1 = (atk1[sq] & 0x4FFF);
  1232.       if (a1 == 0 || a2 > ctlK + 1)
  1233.         {
  1234.         s += HUNGP;
  1235.         ++hung[c1];
  1236.         }
  1237.       else
  1238.           s += ATAKD;
  1239.       }
  1240.     return (s);
  1241. }
  1242.  
  1243.  
  1244.  
  1245.  
  1246. short int
  1247. ScorePosition (register short int side)
  1248.  
  1249. /*
  1250.  * Perform normal static evaluation of board position. A score is generated
  1251.  * for each piece and these are summed to get a score for each side.
  1252.  */
  1253.  
  1254. {
  1255.     register short int score;
  1256.     register short sq, i, xside;
  1257.     short int s;
  1258.     short int escore;
  1259.  
  1260.     UpdateWeights ();
  1261.     xside = side ^ 1;
  1262.     hung[white] = hung[black] = pscore[white] = pscore[black] = 0;
  1263. #ifdef CACHE
  1264.     if (!ProbeEETable (side, &s))
  1265.       {
  1266. #endif
  1267.       for (c1 = white; c1 <= black; c1++)
  1268.         {
  1269.         c2 = c1 ^ 1;
  1270.         /* atk1 is array of atacks on squares by my side */
  1271.         atk1 = atak[c1];
  1272.         /* atk2 is array of atacks on squares by other side */
  1273.         atk2 = atak[c2];
  1274.         /* same for PC1 and PC2 */
  1275.         PC1 = PawnCnt[c1];
  1276.         PC2 = PawnCnt[c2];
  1277.         for (i = PieceCnt[c1]; i >= 0; i--)
  1278.           {
  1279.               sq = PieceList[c1][i];
  1280.               switch (board[sq])
  1281.             {
  1282.             case pawn:
  1283.                 s = PawnValue (sq, side);
  1284.                 break;
  1285.             case knight:
  1286.                 s = KnightValue (sq, side);
  1287.                 break;
  1288.             case bishop:
  1289.                 s = BishopValue (sq, side);
  1290.                 break;
  1291.             case rook:
  1292.                 s = RookValue (sq, side);
  1293.                 break;
  1294.             case queen:
  1295.                 s = QueenValue (sq, side);
  1296.                 break;
  1297.             case king:
  1298.                 s = KingValue (sq, side);
  1299.                 break;
  1300.             default:
  1301.                 s = 0;
  1302.                 break;
  1303.             }
  1304.               pscore[c1] += s;
  1305.               svalue[sq] = s;
  1306.           }
  1307.         }
  1308.     if (hung[side] > 1)
  1309.     pscore[side] += HUNGX;
  1310.     if (hung[xside] > 1)
  1311.     pscore[xside] += HUNGX;
  1312.  
  1313.     score = mtl[side] - mtl[xside] + pscore[side] - pscore[xside] + 10;
  1314.     if (dither)
  1315.       {
  1316.       if (flag.hash)
  1317.           gsrand (starttime + (unsigned int) hashbd);
  1318.       score += urand () % dither;
  1319.       }
  1320.  
  1321.     if (score > 0 && pmtl[side] == 0)
  1322.     if (emtl[side] < valueR)
  1323.         score = 0;
  1324.     else if (score < valueR)
  1325.         score /= 2;
  1326.     if (score < 0 && pmtl[xside] == 0)
  1327.     if (emtl[xside] < valueR)
  1328.         score = 0;
  1329.     else if (-score < valueR)
  1330.         score /= 2;
  1331.  
  1332.     if (mtl[xside] == valueK && emtl[side] > valueB)
  1333.     score += 200;
  1334.     if (mtl[side] == valueK && emtl[xside] > valueB)
  1335.     score -= 200;
  1336. #ifdef CACHE
  1337.     if(PUTVAR)PutInEETable(side,score);
  1338. #endif
  1339.     return (score);
  1340. #ifdef CACHE
  1341. }
  1342. else {
  1343. return s;
  1344. }
  1345. #endif
  1346. }
  1347. static inline void
  1348. BlendBoard (const short int a[64], const short int b[64], short int c[64])
  1349. {
  1350.     register int sq, s;
  1351.     s = 10 - stage;
  1352.     for (sq = 0; sq < 64; sq++)
  1353.     c[sq] = ((a[sq] * s) + (b[sq] * stage)) / 10;
  1354. }
  1355.  
  1356.  
  1357. static inline void
  1358. CopyBoard (const short int a[64], short int b[64])
  1359. {
  1360.     register short *sqa, *sqb;
  1361.     for (sqa = a, sqb = b; sqa < a + 64;)
  1362.     *sqb++ = *sqa++;
  1363. }
  1364.  
  1365.  
  1366. void
  1367. ExaminePosition (void)
  1368.  
  1369. /*
  1370.  * This is done one time before the search is started. Set up arrays Mwpawn,
  1371.  * Mbpawn, Mknight, Mbishop, Mking which are used in the SqValue() function
  1372.  * to determine the positional value of each piece.
  1373.  */
  1374.  
  1375. {
  1376.     register short i, sq;
  1377.     register short fyle;
  1378.     short wpadv, bpadv, wstrong, bstrong, z, side, pp, j, k, val, Pd, rank;
  1379.     static short PawnStorm = false;
  1380.  
  1381.     ataks (white, atak[white]);
  1382.     ataks (black, atak[black]);
  1383.     UpdateWeights ();
  1384.     HasKnight[white] = HasKnight[black] = 0;
  1385.     HasBishop[white] = HasBishop[black] = 0;
  1386.     HasRook[white] = HasRook[black] = 0;
  1387.     HasQueen[white] = HasQueen[black] = 0;
  1388.     for (side = white; side <= black; side++)
  1389.     for (i = PieceCnt[side]; i >= 0; i--)
  1390.         switch (board[PieceList[side][i]])
  1391.           {
  1392.           case knight:
  1393.           ++HasKnight[side];
  1394.           break;
  1395.           case bishop:
  1396.           ++HasBishop[side];
  1397.           break;
  1398.           case rook:
  1399.           ++HasRook[side];
  1400.           break;
  1401.           case queen:
  1402.           ++HasQueen[side];
  1403.           break;
  1404.           }
  1405.     if (!Developed[white])
  1406.     Developed[white] = (board[1] != knight && board[2] != bishop &&
  1407.                 board[5] != bishop && board[6] != knight);
  1408.     if (!Developed[black])
  1409.     Developed[black] = (board[57] != knight && board[58] != bishop &&
  1410.                 board[61] != bishop && board[62] != knight);
  1411.     if (!PawnStorm && stage < 5)
  1412.     PawnStorm = ((column (wking) < 3 && column (bking) > 4) ||
  1413.              (column (wking) > 4 && column (bking) < 3));
  1414.  
  1415.     CopyBoard (pknight, Mknight[white]);
  1416.     CopyBoard (pknight, Mknight[black]);
  1417.     CopyBoard (pbishop, Mbishop[white]);
  1418.     CopyBoard (pbishop, Mbishop[black]);
  1419.     BlendBoard (KingOpening, KingEnding, Mking[white]);
  1420.     BlendBoard (KingOpening, KingEnding, Mking[black]);
  1421.  
  1422.     for (sq = 0; sq < 64; sq++)
  1423.       {
  1424.       fyle = column (sq);
  1425.       rank = row (sq);
  1426.       wstrong = bstrong = true;
  1427.       for (i = sq; i < 64; i += 8)
  1428.           if (Patak (black, i))
  1429.         {
  1430.             wstrong = false;
  1431.             break;
  1432.         }
  1433.       for (i = sq; i >= 0; i -= 8)
  1434.           if (Patak (white, i))
  1435.         {
  1436.             bstrong = false;
  1437.             break;
  1438.         }
  1439.       wpadv = bpadv = PADVNCM;
  1440.       if ((fyle == 0 || PawnCnt[white][fyle - 1] == 0) && (fyle == 7 || PawnCnt[white][fyle + 1] == 0))
  1441.           wpadv = PADVNCI;
  1442.       if ((fyle == 0 || PawnCnt[black][fyle - 1] == 0) && (fyle == 7 || PawnCnt[black][fyle + 1] == 0))
  1443.           bpadv = PADVNCI;
  1444.       Mwpawn[sq] = (wpadv * PawnAdvance[sq]) / 10;
  1445.       Mbpawn[sq] = (bpadv * PawnAdvance[63 - sq]) / 10;
  1446.       Mwpawn[sq] += PawnBonus;
  1447.       Mbpawn[sq] += PawnBonus;
  1448.       if (Mvboard[kingP[white]])
  1449.         {
  1450.         if ((fyle < 3 || fyle > 4) && distance (sq, wking) < 3)
  1451.             Mwpawn[sq] += PAWNSHIELD;
  1452.         }
  1453.       else if (rank < 3 && (fyle < 2 || fyle > 5))
  1454.           Mwpawn[sq] += PAWNSHIELD / 2;
  1455.       if (Mvboard[kingP[black]])
  1456.         {
  1457.         if ((fyle < 3 || fyle > 4) && distance (sq, bking) < 3)
  1458.             Mbpawn[sq] += PAWNSHIELD;
  1459.         }
  1460.       else if (rank > 4 && (fyle < 2 || fyle > 5))
  1461.           Mbpawn[sq] += PAWNSHIELD / 2;
  1462.       if (PawnStorm)
  1463.         {
  1464.         if ((column (wking) < 4 && fyle > 4) || (column (wking) > 3 && fyle < 3))
  1465.             Mwpawn[sq] += 3 * rank - 21;
  1466.         if ((column (bking) < 4 && fyle > 4) || (column (bking) > 3 && fyle < 3))
  1467.             Mbpawn[sq] -= 3 * rank;
  1468.         }
  1469.       Mknight[white][sq] += 5 - distance (sq, bking);
  1470.       Mknight[white][sq] += 5 - distance (sq, wking);
  1471.       Mknight[black][sq] += 5 - distance (sq, wking);
  1472.       Mknight[black][sq] += 5 - distance (sq, bking);
  1473.       Mbishop[white][sq] += BishopBonus;
  1474.       Mbishop[black][sq] += BishopBonus;
  1475.       for (i = PieceCnt[black]; i >= 0; i--)
  1476.           if (distance (sq, PieceList[black][i]) < 3)
  1477.           Mknight[white][sq] += KNIGHTPOST;
  1478.       for (i = PieceCnt[white]; i >= 0; i--)
  1479.           if (distance (sq, PieceList[white][i]) < 3)
  1480.           Mknight[black][sq] += KNIGHTPOST;
  1481.       if (wstrong)
  1482.           Mknight[white][sq] += KNIGHTSTRONG;
  1483.       if (bstrong)
  1484.           Mknight[black][sq] += KNIGHTSTRONG;
  1485.       if (wstrong)
  1486.           Mbishop[white][sq] += BISHOPSTRONG;
  1487.       if (bstrong)
  1488.           Mbishop[black][sq] += BISHOPSTRONG;
  1489.  
  1490.       if (HasBishop[white] == 2)
  1491.           Mbishop[white][sq] += 8;
  1492.       if (HasBishop[black] == 2)
  1493.           Mbishop[black][sq] += 8;
  1494.       if (HasKnight[white] == 2)
  1495.           Mknight[white][sq] += 5;
  1496.       if (HasKnight[black] == 2)
  1497.           Mknight[black][sq] += 5;
  1498.  
  1499.       Kfield[white][sq] = Kfield[black][sq] = 0;
  1500.       if (distance (sq, wking) == 1)
  1501.           Kfield[black][sq] = KATAK;
  1502.       if (distance (sq, bking) == 1)
  1503.           Kfield[white][sq] = KATAK;
  1504.       Pd = 0;
  1505.       for (k = 0; k <= PieceCnt[white]; k++)
  1506.         {
  1507.         i = PieceList[white][k];
  1508.         if (board[i] == pawn)
  1509.           {
  1510.               pp = true;
  1511.               z = i + ((row (i) == 6) ? 8 : 16);
  1512.               for (j = i + 8; j < 64; j += 8)
  1513.               if (Patak (black, j) || board[j] == pawn)
  1514.                 {
  1515.                 pp = false;
  1516.                 break;
  1517.                 }
  1518.               Pd += ((pp) ? 5 * taxicab (sq, z) : taxicab (sq, z));
  1519.           }
  1520.         }
  1521.       for (k = 0; k <= PieceCnt[black]; k++)
  1522.         {
  1523.         i = PieceList[black][k];
  1524.         if (board[i] == pawn)
  1525.           {
  1526.               pp = true;
  1527.               z = i - ((row (i) == 1) ? 8 : 16);
  1528.               for (j = i - 8; j >= 0; j -= 8)
  1529.               if (Patak (white, j) || board[j] == pawn)
  1530.                 {
  1531.                 pp = false;
  1532.                 break;
  1533.                 }
  1534.               Pd += ((pp) ? 5 * taxicab (sq, z) : taxicab (sq, z));
  1535.           }
  1536.         }
  1537.       if (Pd != 0)
  1538.         {
  1539.         val = (Pd * stage2) / 10;
  1540.         Mking[white][sq] -= val;
  1541.         Mking[black][sq] -= val;
  1542.         }
  1543.       }
  1544. }
  1545.  
  1546. void
  1547. UpdateWeights (void)
  1548.  
  1549. /*
  1550.  * If material balance has changed, determine the values for the positional
  1551.  * evaluation terms.
  1552.  */
  1553.  
  1554. {
  1555.     register short s1;
  1556.  
  1557.     emtl[white] = mtl[white] - pmtl[white] - valueK;
  1558.     emtl[black] = mtl[black] - pmtl[black] - valueK;
  1559.     tmtl = emtl[white] + emtl[black];
  1560.     s1 = ((tmtl > 6600) ? 0 : ((tmtl < 1400) ? 10 : (6600 - tmtl) / 520));
  1561.     if (s1 != stage)
  1562.       {
  1563.       stage = s1;
  1564.       stage2 = ((tmtl > 3600) ? 0 : ((tmtl < 1400) ? 10 : (3600 - tmtl) / 220));
  1565.       PEDRNK2B = -15;    /* centre pawn on 2nd rank & blocked */
  1566.       PBLOK = -4;        /* blocked backward pawn */
  1567.       PDOUBLED = -14;    /* doubled pawn */
  1568.       PWEAKH = -4;        /* weak pawn on half open file */
  1569.       PAWNSHIELD = 10 - stage;    /* pawn near friendly king */
  1570.       PADVNCM = 10;        /* advanced pawn multiplier */
  1571.       PADVNCI = 7;        /* muliplier for isolated pawn */
  1572.       PawnBonus = stage;
  1573.  
  1574.       KNIGHTPOST = (stage + 2) / 3;    /* knight near enemy pieces */
  1575.       KNIGHTSTRONG = (stage + 6) / 2;    /* occupies pawn hole */
  1576.  
  1577.       BISHOPSTRONG = (stage + 6) / 2;    /* occupies pawn hole */
  1578.       BishopBonus = BBONUS * stage;
  1579.  
  1580.       RHOPN = 10;        /* rook on half open file */
  1581.       RHOPNX = 4;
  1582.       RookBonus = RBONUS * stage;
  1583.  
  1584.       XRAY = 8;        /* Xray attack on piece */
  1585.       PINVAL = 10;        /* Pin */
  1586.  
  1587.       KHOPN = (3 * stage - 30) / 2;    /* king on half open file */
  1588.       KHOPNX = KHOPN / 2;
  1589.       KCASTLD = 10 - stage;
  1590.       KMOVD = -40 / (stage + 1);    /* king moved before castling */
  1591.       KATAK = (10 - stage) / 2;    /* B,R attacks near enemy king */
  1592.       KSFTY = ((stage < 8) ? (KINGSAFETY - 4 * stage) : 0);
  1593.  
  1594.       ATAKD = -6;        /* defender > attacker */
  1595.       HUNGP = -12;        /* each hung piece */
  1596.       HUNGX = -18;        /* extra for >1 hung piece */
  1597.       }
  1598. }
  1599.  
  1600.